UNICEF [Link]

  1. 世界では、六人に一人(3億5600万人)の子どもたちが「極度にまずしい」暮らしをしています。

どのようなデータから、このようなことがわかるのでしょうか。まずは、極度の貧困とは、どのように定義しているのでしょうか。

準備

Step 1. (R に機能を付け加える)パッケージのインストール(最初だけ)

install.packages("tidyverse")
install.packages("WDI")

Step 2. パッケージを使えるように読み込みます。

library(tidyverse)
── Attaching core tidyverse packages ──────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.3     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.4     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.0
✔ purrr     1.0.2     ── Conflicts ────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(WDI)

Step 3. データを保存するための data という名前のディレクトリ(フォルダー)を作成します。(最初だけ)

dir.create("data")
Warning: 'data' already exists

Step 4. エラーが生じた時に、調べやすいので、‘システム言語(System Language)’ を英語にしておきます。(最初だけ)

Sys.setenv(LANG = "en")

Step 5. データを読み込みます。WDI パッケージをつかうと、簡単に、データを読み込むことができます。わかりやすい名前(gdp、gdppcap)をつけ、人口(pop)も読み込んでおきます。extra = TRUE としておくと、使い情報を一緒に読み込むことができます。(すでに、data に、gdppcap.csv というのがあるときは、Step 5, Step 6 はスキップして、Step 7 だけを実行します。)

df_gdppcap <- WDI(indicator = c(gdp = "NY.GDP.MKTP.PP.KD", pop = "SP.POP.TOTL", gdppcap = "NY.GDP.PCAP.PP.KD"), extra = TRUE)

Step 6. 何度も読み込むのは、時間もかかりますから、最初に作った、data という、ディレクトリー(フォルダ)に保存しておきます。(すでに、data に、gdppcap.csv というのがあるときは、Step 5, Step 6 はスキップして、Step 7 だけを実行します。)

write_csv(df_gdppcap, "data/gdppcap.csv")

Step 7. 保存したものを読み込みます。(すでに、data に、gdppcap.csv というのがあるときは、Step 5, Step 6 はスキップして、Step 7 だけを実行します。)

df_gdppcap <- read_csv("data/gdppcap.csv")
Rows: 16758 Columns: 15── Column specification ───────────────────────────────────────────────────────────────
Delimiter: ","
chr  (7): country, iso2c, iso3c, region, capital, income, lending
dbl  (6): year, gdp, pop, gdppcap, longitude, latitude
lgl  (1): status
date (1): lastupdated
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Step 8. データの最初の6行(rows)をみてみます。

head(df_gdppcap)

Step 9. データの列(columns、変数 variables)はどのようなものがあるかを表示します。

str(df_gdppcap)
spc_tbl_ [16,758 × 15] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ country    : chr [1:16758] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
 $ iso2c      : chr [1:16758] "AF" "AF" "AF" "AF" ...
 $ iso3c      : chr [1:16758] "AFG" "AFG" "AFG" "AFG" ...
 $ year       : num [1:16758] 2014 1971 2006 2013 1995 ...
 $ status     : logi [1:16758] NA NA NA NA NA NA ...
 $ lastupdated: Date[1:16758], format: "2023-10-26" "2023-10-26" ...
 $ gdp        : num [1:16758] 7.02e+10 NA 3.48e+10 6.83e+10 NA ...
 $ pop        : num [1:16758] 32716210 11015857 25442944 31541209 16418912 ...
 $ gdppcap    : num [1:16758] 2144 NA 1367 2165 NA ...
 $ region     : chr [1:16758] "South Asia" "South Asia" "South Asia" "South Asia" ...
 $ capital    : chr [1:16758] "Kabul" "Kabul" "Kabul" "Kabul" ...
 $ longitude  : num [1:16758] 69.2 69.2 69.2 69.2 69.2 ...
 $ latitude   : num [1:16758] 34.5 34.5 34.5 34.5 34.5 ...
 $ income     : chr [1:16758] "Low income" "Low income" "Low income" "Low income" ...
 $ lending    : chr [1:16758] "IDA" "IDA" "IDA" "IDA" ...
 - attr(*, "spec")=
  .. cols(
  ..   country = col_character(),
  ..   iso2c = col_character(),
  ..   iso3c = col_character(),
  ..   year = col_double(),
  ..   status = col_logical(),
  ..   lastupdated = col_date(format = ""),
  ..   gdp = col_double(),
  ..   pop = col_double(),
  ..   gdppcap = col_double(),
  ..   region = col_character(),
  ..   capital = col_character(),
  ..   longitude = col_double(),
  ..   latitude = col_double(),
  ..   income = col_character(),
  ..   lending = col_character()
  .. )
 - attr(*, "problems")=<externalptr> 

Step 10. (ちょっと高度ですが)region, income, lending には、どのようなものがあるか、みてみます。

df_gdppcap |> select(region, income, lending) |> lapply(unique)
$region
[1] "South Asia"                 "Aggregates"                
[3] "Europe & Central Asia"      "Middle East & North Africa"
[5] "East Asia & Pacific"        "Sub-Saharan Africa"        
[7] "Latin America & Caribbean"  "North America"             
[9] NA                          

$income
[1] "Low income"          "Aggregates"          "Upper middle income"
[4] "Lower middle income" "High income"         NA                   
[7] "Not classified"     

$lending
[1] "IDA"            "Aggregates"     "IBRD"           "Not classified"
[5] "Blend"          NA              

Step 11. 世界の GDP の推移(経年変化)を見てみます。

COUNTRY <- "World"
df_gdppcap |> filter(country == COUNTRY) |> drop_na(gdppcap) |>
  ggplot(aes(year, gdp)) + geom_line()

Step 12. 世界の GDP per Capita の推移(経年変化)を見てみます。

COUNTRY <- "World"
df_gdppcap |> filter(country == COUNTRY) |> drop_na(gdppcap) |>
  ggplot(aes(year, gdppcap)) + geom_line()

Step 13. 人口の推移(経年変化)もみてみましょう。

COUNTRY <- "World"
df_gdppcap |> filter(country == COUNTRY) |>
  ggplot(aes(year, pop)) + geom_line()

Step 14. 2022年の、GDP の多い国から順に並べてみましょう。

arrange(desc(gdp)) とすると、大きい順, arrange(gdp) とすると小さい順に並びます。

df_gdppcap |> filter(year == 2022, region != "Aggregates") |> 
  drop_na(gdp) |> arrange(desc(gdp))

Step 15. 2022年の、GDP per Capita の多い国から順に並べてみましょう。

df_gdppcap |> filter(year == 2022, region != "Aggregates") |> 
  drop_na(gdppcap) |> arrange(desc(gdppcap))

Step 16. 2022年の、Population(人口) の多い国から順に並べてみましょう。

df_gdppcap |> filter(year == 2022, region != "Aggregates") |> 
  drop_na(pop) |> arrange(desc(pop))

Step 17. 2022年の、GDP と Population(人口) の関係性を、散布図(Scatter Plot)で見てみましょう。

df_gdppcap2 |> filter(year == 2022, region !="Aggregates") |> 
  drop_na(gdp, pop) |> 
  ggplot(aes(pop, gdp)) + geom_point()

Step 18. 左横に固まっていましたから、対数表示にしてみます。

df_gdppcap2 |> filter(year == 2022, region !="Aggregates") |> 
  drop_na(gdp, pop) |> 
  ggplot(aes(pop, gdp)) + geom_point() + 
  scale_x_log10() + scale_y_log10()

Step 19. 直線的に増加しているように、見えますから、近似直線(回帰直線といいます)を描いてみます。

df_gdppcap2 |> filter(year == 2022, region !="Aggregates") |> 
  drop_na(gdp, pop) |> 
  ggplot(aes(pop, gdp)) + geom_point() + 
  geom_smooth(method = "lm", formula = 'y ~ x', se = FALSE) +
  scale_x_log10() + scale_y_log10()

Step 20. 直線の方程式(Coefficients)や、どのぐらい、当てはまっているか(Residual R-squared)もみることができます。

df_gdppcap2 |> filter(year == 2022, region !="Aggregates") |> 
  drop_na(gdp, pop) |> lm(log10(gdp) ~ log10(pop), data = _) |> summary()

Call:
lm(formula = log10(gdp) ~ log10(pop), data = drop_na(filter(df_gdppcap2, 
    year == 2022, region != "Aggregates"), gdp, pop))

Residuals:
     Min       1Q   Median       3Q      Max 
-1.22646 -0.39512  0.03996  0.42553  0.95842 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  4.45320    0.27485   16.20   <2e-16 ***
log10(pop)   0.94704    0.03998   23.69   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.5117 on 181 degrees of freedom
Multiple R-squared:  0.7561,    Adjusted R-squared:  0.7548 
F-statistic: 561.2 on 1 and 181 DF,  p-value: < 2.2e-16

Step 21. 地域や、収入レベルも色や、形で表示することが可能です。

df_gdppcap2 |> filter(year == 2020, region !="Aggregates") |> 
  drop_na(gdp, pop) |> 
  ggplot(aes(pop, gdp, color = region, shape = income)) + geom_point() + 
  scale_x_log10() + scale_y_log10()

Step 22. これは、一人当たりの GDP を地域と、人口の情報も入れて表示したものです。

df_gdppcap2 |> filter(year == 2020, region !="Aggregates") |> 
  drop_na(gdp, gdppcap, pop) |> 
  ggplot(aes(gdppcap, gdp, color = region, size = pop)) + geom_point() + 
  scale_x_log10() + scale_y_log10()

Step 23. 他のパッケージを使うと、対話型のグラフを作成することも可能です。

install.packages("plotly")
trying URL 'https://cran.ism.ac.jp/bin/macosx/big-sur-arm64/contrib/4.3/plotly_4.10.3.tgz'
Content type 'application/x-gzip' length 3199222 bytes (3.1 MB)
==================================================
downloaded 3.1 MB

The downloaded binary packages are in
    /var/folders/mc/15j2lx113vscs17fxhz_p7400000gn/T//RtmpVDrgz9/downloaded_packages

Step 23. これは、一人当たりの GDP を地域と、人口の情報も入れて表示したものです。

library(plotly)
test <- df_gdppcap2 |> filter(year == 2020, region !="Aggregates") |> drop_na(gdp, pop) |> 
  ggplot(aes(color = country, shape = region, pop, gdp)) + geom_point() + 
  scale_x_log10() + scale_y_log10() + theme(legend.position = "none")
test |> ggplotly()
Warning: The shape palette can deal with a maximum of 6 discrete values because more
than 6 becomes difficult to discriminate; you have 7. Consider specifying
shapes manually if you must have them.

Step 24. 一人当たりのGDP の2022年の分布をみてみましょう。

df_gdppcap |> filter(year == 2022, region != "Aggregates") |> drop_na(gdppcap) |> 
  ggplot(aes(gdppcap)) + geom_histogram(binwidth = 10000)

Step 25. 対数表示にするとどうなるでううか。

df_gdppcap |> filter(year == 2022, region != "Aggregates") |> drop_na(gdppcap) |> 
  ggplot(aes(gdppcap)) + geom_histogram(bins = 10) + scale_x_log10()

Step 26. 箱ひげ図で見てみましょう。

df_gdppcap2 |> filter(year == 2020) |> drop_na(gdppcap) |> 
  filter(income != "Aggregates") |> 
  ggplot(aes(gdppcap, factor(income, levels = c("High income", "Upper middle income", "Lower middle income", "Low income")), fill = income)) + geom_boxplot() + scale_x_log10() +
  labs(y = "") +
  theme(legend.position = "none")

LS0tCnRpdGxlOiAi5qW15bqm44Gr6LKn44GX44GE77yB77yfIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgZGZfcHJpbnQ6IHBhZ2VkCiMgICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKIyAgICB0b2M6IHllcwojICAgIHRvY19mbG9hdDogeWVzCi0tLQoKPiBVTklDRUYgW1tMaW5rXShodHRwczovL3d3dy51bmljZWYub3IuanAva29kb21vL3NkZ3MvMTdnb2Fscy8xLXBvdmVydHkvKV0KPgo+IDEuICDkuJbnlYzjgafjga/jgIHlha3kurrjgavkuIDkurrvvIgz5YSENTYwMOS4h+S6uu+8ieOBruWtkOOBqeOCguOBn+OBoeOBjOOAjOalteW6puOBq+OBvuOBmuOBl+OBhOOAjeaaruOCieOBl+OCkuOBl+OBpuOBhOOBvuOBmeOAggoK44Gp44Gu44KI44GG44Gq44OH44O844K/44GL44KJ44CB44GT44Gu44KI44GG44Gq44GT44Go44GM44KP44GL44KL44Gu44Gn44GX44KH44GG44GL44CC44G+44Ga44Gv44CB5qW15bqm44Gu6LKn5Zuw44Go44Gv44CB44Gp44Gu44KI44GG44Gr5a6a576p44GX44Gm44GE44KL44Gu44Gn44GX44KH44GG44GL44CCCgojIyMjIEZhY3QgU2hlZXQ6IEFuIEFkanVzdG1lbnQgdG8gR2xvYmFsIFBvdmVydHkgTGluZXMgW1tMaW5rXShodHRwczovL3d3dy53b3JsZGJhbmsub3JnL2VuL25ld3MvZmFjdHNoZWV0LzIwMjIvMDUvMDIvZmFjdC1zaGVldC1hbi1hZGp1c3RtZW50LXRvLWdsb2JhbC1wb3ZlcnR5LWxpbmVzKV0KClRoZSBXb3JsZCBCYW5rIHVwZGF0ZWQgdGhlIGdsb2JhbCBwb3ZlcnR5IGxpbmVzIGluIFNlcHRlbWJlciAyMDIyLiBUaGUgZGVjaXNpb24sIGFubm91bmNlZCBpbiBNYXksIGZvbGxvd3MgdGhlIHJlbGVhc2UgaW4gMjAyMCBvZiBuZXcgcHVyY2hhc2luZyBwb3dlciBwYXJpdGllcyAoUFBQcyktLS10aGUgbWFpbiBkYXRhIHVzZWQgdG8gY29udmVydCBkaWZmZXJlbnQgY3VycmVuY2llcyBpbnRvIGEgY29tbW9uLCBjb21wYXJhYmxlIHVuaXQgYW5kIGFjY291bnQgZm9yIHByaWNlIGRpZmZlcmVuY2VzIGFjcm9zcyBjb3VudHJpZXMuIFRoZSBuZXcgZXh0cmVtZSBwb3ZlcnR5IGxpbmUgb2YgXCQyLjE1IHBlciBwZXJzb24gcGVyIGRheSwgd2hpY2ggcmVwbGFjZXMgdGhlIFwkMS45MCBwb3ZlcnR5IGxpbmUsIGlzIGJhc2VkIG9uIDIwMTcgUFBQcy4gSGVyZSB5b3UgZmluZCBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoaXMgY2hhbmdlIGFuZCB3aGF0IGl0IG1lYW5zIGZvciBtZWFzdXJpbmcgZ2xvYmFsIHBvdmVydHkuCgrkuJbnlYzpioDooYzjga8yMDIy5bm0OeaciOOBq+S4lueVjOOBruiyp+WbsOODqeOCpOODs+OCkuabtOaWsOOBl+OBn+OAgjXmnIjjgavnmbrooajjgZXjgozjgZ/jgZPjga7msbrlrprjga/jgIEyMDIw5bm044Gr5paw6LO86LK35Yqb5bmz5L6h77yIUFBQ77yJ44GM55m66KGo44GV44KM44Gf44GT44Go44KS5Y+X44GR44Gm44Gu44KC44Gu44Gn44GC44KL44CC5paw6LO86LK35Yqb5bmz5L6h77yIUFBQ77yJ44Go44Gv44CB44GV44G+44GW44G+44Gq6YCa6LKo44KS5YWx6YCa44Gu5q+U6LyD5Y+v6IO944Gq5Y2Y5L2N44Gr5aSJ5o+b44GX44CB6LKn5Zuw44Gu56+E5Zuy44KS6Kqs5piO44GZ44KL44Gf44KB44Gr5L2/55So44GV44KM44KL5Li76KaB44Gq44OH44O844K/44Gn44GC44KL44CC5Zu944GU44Go44Gu5L6h5qC85beu44CCMS45MOODieODq+OBruiyp+WbsOe3muOBq+S7o+OCj+OCi+OAgTHkurrlvZPjgZ/jgoox5pel5b2T44Gf44KKMi4xNeODieODq+OBqOOBhOOBhuaWsOOBn+OBqualteW6puOBruiyp+WbsOe3muOBr+OAgTIwMTflubTjga5QUFDjgavln7rjgaXjgYTjgabjgYTjgovjgILjgZPjgZPjgafjga/jgIHjgZPjga7lpInljJbjgajjgZ3jgozjgYzkuJbnlYzjga7osqflm7Djga7muKzlrprjgavkvZXjgpLmhI/lkbPjgZnjgovjgYvjgavplqLjgZnjgovoqbPntLDmg4XloLHjgpLjgZTopqfjgYTjgZ/jgaDjgZHjgb7jgZnjgIIKCuOBneOBk+OBp+OAgeOBk+OBruizvOiyt+WKm+W5s+S+oe+8iFBQUDogcHVyY2hhc2luZyBwb3dlciBwYXJpdGllc++8ieOCkuOBvuOBmuOBr+OAgeiqv+OBueOBpuOBv+OBvuOBl+OCh+OBhuOAguWbveOChOOAgeWcsOWfn+OBlOOBqOOBruOAgUdEUCwgUFBQIOOBqOiogOOCj+OCjOOCi+OCguOBruOBqOOAgeOBneOCjOOCkuOAgeS6uuWPo+OBp+WJsuOBo+OBn+OAgeS4gOS6uuW9k+OBn+OCiuOBruOAgUdEUCBQUFAg44Go6KiA44KP44KM44KL44KC44Gu44Gn44GZ44CCMjAxN+W5tOOCkuWfuua6luOBqOOBl+OBpuOAgeOCpOODs+ODleODrOeOh+OCkuiqv+aVtOOBl+OBpuOBguOCiuOBvuOBmeOAgkdEUCDjga/lm73lhoXnt4/nlJ/nlKPvvIhHcm9zcyBEb21lc3RpYyBQcm9kb2N077yJ44Gu55Wl44Gn44CB5L2V56iu6aGe44GL6KiI566X5pa55rOV44GM44GC44KK44G+44GZ44GM44CB5Z+65pys55qE44Gq57WM5riI5oyH5qiZ44Gn44CB44OJ44Or5o+b566X44GV44KM44Gm44GE44G+44GZ44CCCgotICAgR0RQLCBQUFAgKGNvbnN0YW50IDIwMTcgaW50ZXJuYXRpb25hbCBcJCk6IE5ZLkdEUC5NS1RQLlBQLktECi0gICBHRFAgcGVyIGNhcGl0YSwgUFBQIChjb25zdGFudCAyMDE3IGludGVybmF0aW9uYWwgXCQpOiBOWS5HRFAuUENBUC5QUC5LRAoKR0RQLCBQUFAgKGNvbnN0YW50IDIwMTcgaW50ZXJuYXRpb25hbCBcJCkg44Go44GL44CBR0RQIHBlciBjYXBpdGEsIFBQUCAoY29uc3RhbnQgMjAxNyBpbnRlcm5hdGlvbmFsIFwkKSDjgpLjgIHmjIfmqJnlkI3vvIhJbmRpY2F0b3IgTmFtZe+8ieOBqOOBhOOBhOOAgU5ZLkdEUC5NS1RQLlBQLktEIOOBqOOBi+OAgU5ZLkdEUC5QQ0FQLlBQLktEIOOCkuOAgeaMh+aomeOCs+ODvOODie+8iEluZGljYXRvciBDb2Rl77yJ44Go6KiA44GE44G+44GZ44CC5b6M6ICF44KS44CBV0RJ77yI5LiW55WM6ZaL55m65oyH5qiZ44CBV29ybGQgRGV2ZWxvcG1lbnQgSW5kaWNhdG9y77yJ44Go5ZG844G244GT44Go44KC44GC44KK44G+44GZ44CCCgojIyMg5rqW5YKZCgpTdGVwIDEuIO+8iFIg44Gr5qmf6IO944KS5LuY44GR5Yqg44GI44KL77yJ44OR44OD44Kx44O844K444Gu44Kk44Oz44K544OI44O844Or77yI5pyA5Yid44Gg44GR77yJCgpgYGB7ciBldmFsID0gRkFMU0V9Cmluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpCmluc3RhbGwucGFja2FnZXMoIldESSIpCmBgYAoKU3RlcCAyLiDjg5Hjg4PjgrHjg7zjgrjjgpLkvb/jgYjjgovjgojjgYbjgavoqq3jgb/ovrzjgb/jgb7jgZnjgIIKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShXREkpCmBgYAoKU3RlcCAzLiDjg4fjg7zjgr/jgpLkv53lrZjjgZnjgovjgZ/jgoHjga4gZGF0YSDjgajjgYTjgYblkI3liY3jga7jg4fjgqPjg6zjgq/jg4jjg6rvvIjjg5Xjgqnjg6vjg4Djg7zvvInjgpLkvZzmiJDjgZfjgb7jgZnjgILvvIjmnIDliJ3jgaDjgZHvvIkKCmBgYHtyIGNyZWF0ZS1kaXJzfQpkaXIuY3JlYXRlKCJkYXRhIikKYGBgCgpTdGVwIDQuIOOCqOODqeODvOOBjOeUn+OBmOOBn+aZguOBq+OAgeiqv+OBueOChOOBmeOBhOOBruOBp+OAgSfjgrfjgrnjg4bjg6DoqIDoqp7vvIhTeXN0ZW0gTGFuZ3VhZ2XvvIknIOOCkuiLseiqnuOBq+OBl+OBpuOBiuOBjeOBvuOBmeOAgu+8iOacgOWIneOBoOOBke+8iQoKYGBge3IgZXZhbCA9IEZBTFNFfQpTeXMuc2V0ZW52KExBTkcgPSAiZW4iKQpgYGAKClN0ZXAgNS4g44OH44O844K/44KS6Kqt44G/6L6844G/44G+44GZ44CCV0RJIOODkeODg+OCseODvOOCuOOCkuOBpOOBi+OBhuOBqOOAgeewoeWNmOOBq+OAgeODh+ODvOOCv+OCkuiqreOBv+i+vOOCgOOBk+OBqOOBjOOBp+OBjeOBvuOBmeOAguOCj+OBi+OCiuOChOOBmeOBhOWQjeWJje+8iGdkcOOAgWdkcHBjYXDvvInjgpLjgaTjgZHjgIHkurrlj6PvvIhwb3DvvInjgoLoqq3jgb/ovrzjgpPjgafjgYrjgY3jgb7jgZnjgIJleHRyYSA9IFRSVUUg44Go44GX44Gm44GK44GP44Go44CB5L2/44GE5oOF5aCx44KS5LiA57eS44Gr6Kqt44G/6L6844KA44GT44Go44GM44Gn44GN44G+44GZ44CC77yI44GZ44Gn44Gr44CBZGF0YSDjgavjgIFnZHBwY2FwLmNzdiDjgajjgYTjgYbjga7jgYzjgYLjgovjgajjgY3jga/jgIFTdGVwIDUsIFN0ZXAgNiDjga/jgrnjgq3jg4Pjg5fjgZfjgabjgIFTdGVwIDcg44Gg44GR44KS5a6f6KGM44GX44G+44GZ44CC77yJCgpgYGB7ciBjYWNoZSA9IFRSVUUsIGV2YWwgPSBGQUxTRX0KZGZfZ2RwcGNhcCA8LSBXREkoaW5kaWNhdG9yID0gYyhnZHAgPSAiTlkuR0RQLk1LVFAuUFAuS0QiLCBwb3AgPSAiU1AuUE9QLlRPVEwiLCBnZHBwY2FwID0gIk5ZLkdEUC5QQ0FQLlBQLktEIiksIGV4dHJhID0gVFJVRSkKYGBgCgpTdGVwIDYuIOS9leW6puOCguiqreOBv+i+vOOCgOOBruOBr+OAgeaZgumWk+OCguOBi+OBi+OCiuOBvuOBmeOBi+OCieOAgeacgOWIneOBq+S9nOOBo+OBn+OAgWRhdGEg44Go44GE44GG44CB44OH44Kj44Os44Kv44OI44Oq44O877yI44OV44Kp44Or44OA77yJ44Gr5L+d5a2Y44GX44Gm44GK44GN44G+44GZ44CC77yI44GZ44Gn44Gr44CBZGF0YSDjgavjgIFnZHBwY2FwLmNzdiDjgajjgYTjgYbjga7jgYzjgYLjgovjgajjgY3jga/jgIFTdGVwIDUsIFN0ZXAgNiDjga/jgrnjgq3jg4Pjg5fjgZfjgabjgIFTdGVwIDcg44Gg44GR44KS5a6f6KGM44GX44G+44GZ44CC77yJCgpgYGB7ciBldmFsID0gRkFMU0V9CndyaXRlX2NzdihkZl9nZHBwY2FwLCAiZGF0YS9nZHBwY2FwLmNzdiIpCmBgYAoKU3RlcCA3LiDkv53lrZjjgZfjgZ/jgoLjga7jgpLoqq3jgb/ovrzjgb/jgb7jgZnjgILvvIjjgZnjgafjgavjgIFkYXRhIOOBq+OAgWdkcHBjYXAuY3N2IOOBqOOBhOOBhuOBruOBjOOBguOCi+OBqOOBjeOBr+OAgVN0ZXAgNSwgU3RlcCA2IOOBr+OCueOCreODg+ODl+OBl+OBpuOAgVN0ZXAgNyDjgaDjgZHjgpLlrp/ooYzjgZfjgb7jgZnjgILvvIkKCmBgYHtyfQpkZl9nZHBwY2FwIDwtIHJlYWRfY3N2KCJkYXRhL2dkcHBjYXAuY3N2IikKYGBgCgpTdGVwIDguIOODh+ODvOOCv+OBruacgOWIneOBru+8luihjO+8iHJvd3PvvInjgpLjgb/jgabjgb/jgb7jgZnjgIIKCmBgYHtyfQpoZWFkKGRmX2dkcHBjYXApCmBgYAoKU3RlcCA5LiDjg4fjg7zjgr/jga7liJfvvIhjb2x1bW5z44CB5aSJ5pWw44CAdmFyaWFibGVz77yJ44Gv44Gp44Gu44KI44GG44Gq44KC44Gu44GM44GC44KL44GL44KS6KGo56S644GX44G+44GZ44CCCgpgYGB7cn0Kc3RyKGRmX2dkcHBjYXApCmBgYAoKU3RlcCAxMC4g77yI44Gh44KH44Gj44Go6auY5bqm44Gn44GZ44GM77yJcmVnaW9uLCBpbmNvbWUsIGxlbmRpbmcg44Gr44Gv44CB44Gp44Gu44KI44GG44Gq44KC44Gu44GM44GC44KL44GL44CB44G/44Gm44G/44G+44GZ44CCCgpgYGB7cn0KZGZfZ2RwcGNhcCB8PiBzZWxlY3QocmVnaW9uLCBpbmNvbWUsIGxlbmRpbmcpIHw+IGxhcHBseSh1bmlxdWUpCmBgYAoKU3RlcCAxMS4g5LiW55WM44Gu44CAR0RQIOOBruaOqOenu++8iOe1jOW5tOWkieWMlu+8ieOCkuimi+OBpuOBv+OBvuOBmeOAggoKYGBge3J9CkNPVU5UUlkgPC0gIldvcmxkIgpkZl9nZHBwY2FwIHw+IGZpbHRlcihjb3VudHJ5ID09IENPVU5UUlkpIHw+IGRyb3BfbmEoZ2RwcGNhcCkgfD4KICBnZ3Bsb3QoYWVzKHllYXIsIGdkcCkpICsgZ2VvbV9saW5lKCkKYGBgCgpTdGVwIDEyLiDkuJbnlYzjga7jgIBHRFAgcGVyIENhcGl0YSDjga7mjqjnp7vvvIjntYzlubTlpInljJbvvInjgpLopovjgabjgb/jgb7jgZnjgIIKCmBgYHtyfQpDT1VOVFJZIDwtICJXb3JsZCIKZGZfZ2RwcGNhcCB8PiBmaWx0ZXIoY291bnRyeSA9PSBDT1VOVFJZKSB8PiBkcm9wX25hKGdkcHBjYXApIHw+CiAgZ2dwbG90KGFlcyh5ZWFyLCBnZHBwY2FwKSkgKyBnZW9tX2xpbmUoKQpgYGAKClN0ZXAgMTMuIOS6uuWPo+OBruaOqOenu++8iOe1jOW5tOWkieWMlu+8ieOCguOBv+OBpuOBv+OBvuOBl+OCh+OBhuOAggoKYGBge3J9CkNPVU5UUlkgPC0gIldvcmxkIgpkZl9nZHBwY2FwIHw+IGZpbHRlcihjb3VudHJ5ID09IENPVU5UUlkpIHw+CiAgZ2dwbG90KGFlcyh5ZWFyLCBwb3ApKSArIGdlb21fbGluZSgpCmBgYAoKU3RlcCAxNC4gMjAyMuW5tOOBruOAgUdEUCDjga7lpJrjgYTlm73jgYvjgonpoIbjgavkuKbjgbnjgabjgb/jgb7jgZfjgofjgYbjgIIKCmBhcnJhbmdlKGRlc2MoZ2RwKSlgIOOBqOOBmeOCi+OBqOOAgeWkp+OBjeOBhOmghmAsYCBgYXJyYW5nZShnZHApYCDjgajjgZnjgovjgajlsI/jgZXjgYTpoIbjgavkuKbjgbPjgb7jgZnjgIIKCmBgYHtyfQpkZl9nZHBwY2FwIHw+IGZpbHRlcih5ZWFyID09IDIwMjIsIHJlZ2lvbiAhPSAiQWdncmVnYXRlcyIpIHw+IAogIGRyb3BfbmEoZ2RwKSB8PiBhcnJhbmdlKGRlc2MoZ2RwKSkKYGBgCgpTdGVwIDE1LiAyMDIy5bm044Gu44CBR0RQIHBlciBDYXBpdGEg44Gu5aSa44GE5Zu944GL44KJ6aCG44Gr5Lim44G544Gm44G/44G+44GX44KH44GG44CCCgpgYGB7ciBldmFsID0gRkFMU0V9CmRmX2dkcHBjYXAgfD4gZmlsdGVyKHllYXIgPT0gMjAyMiwgcmVnaW9uICE9ICJBZ2dyZWdhdGVzIikgfD4gCiAgZHJvcF9uYShnZHBwY2FwKSB8PiBhcnJhbmdlKGRlc2MoZ2RwcGNhcCkpCmBgYAoKU3RlcCAxNi4gMjAyMuW5tOOBruOAgVBvcHVsYXRpb27vvIjkurrlj6PvvIkg44Gu5aSa44GE5Zu944GL44KJ6aCG44Gr5Lim44G544Gm44G/44G+44GX44KH44GG44CCCgpgYGB7cn0KZGZfZ2RwcGNhcCB8PiBmaWx0ZXIoeWVhciA9PSAyMDIyLCByZWdpb24gIT0gIkFnZ3JlZ2F0ZXMiKSB8PiAKICBkcm9wX25hKHBvcCkgfD4gYXJyYW5nZShkZXNjKHBvcCkpCmBgYAoKU3RlcCAxNy4gMjAyMuW5tOOBruOAgUdEUCDjgaggUG9wdWxhdGlvbu+8iOS6uuWPo++8iSDjga7plqLkv4LmgKfjgpLjgIHmlaPluIPlm7PvvIhTY2F0dGVyIFBsb3TvvInjgafopovjgabjgb/jgb7jgZfjgofjgYbjgIIKCmBgYHtyfQpkZl9nZHBwY2FwMiB8PiBmaWx0ZXIoeWVhciA9PSAyMDIyLCByZWdpb24gIT0iQWdncmVnYXRlcyIpIHw+IAogIGRyb3BfbmEoZ2RwLCBwb3ApIHw+IAogIGdncGxvdChhZXMocG9wLCBnZHApKSArIGdlb21fcG9pbnQoKQpgYGAKClN0ZXAgMTguIOW3puaoquOBq+WbuuOBvuOBo+OBpuOBhOOBvuOBl+OBn+OBi+OCieOAgeWvvuaVsOihqOekuuOBq+OBl+OBpuOBv+OBvuOBmeOAggoKYGBge3J9CmRmX2dkcHBjYXAyIHw+IGZpbHRlcih5ZWFyID09IDIwMjIsIHJlZ2lvbiAhPSJBZ2dyZWdhdGVzIikgfD4gCiAgZHJvcF9uYShnZHAsIHBvcCkgfD4gCiAgZ2dwbG90KGFlcyhwb3AsIGdkcCkpICsgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpCmBgYAoKU3RlcCAxOS4g55u057ea55qE44Gr5aKX5Yqg44GX44Gm44GE44KL44KI44GG44Gr44CB6KaL44GI44G+44GZ44GL44KJ44CB6L+R5Ly855u057ea77yI5Zue5biw55u057ea44Go44GE44GE44G+44GZ77yJ44KS5o+P44GE44Gm44G/44G+44GZ44CCCgpgYGB7cn0KZGZfZ2RwcGNhcDIgfD4gZmlsdGVyKHllYXIgPT0gMjAyMiwgcmVnaW9uICE9IkFnZ3JlZ2F0ZXMiKSB8PiAKICBkcm9wX25hKGdkcCwgcG9wKSB8PiAKICBnZ3Bsb3QoYWVzKHBvcCwgZ2RwKSkgKyBnZW9tX3BvaW50KCkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gJ3kgfiB4Jywgc2UgPSBGQUxTRSkgKwogIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKQpgYGAKClN0ZXAgMjAuIOebtOe3muOBruaWueeoi+W8j++8iENvZWZmaWNpZW50c++8ieOChOOAgeOBqeOBruOBkOOCieOBhOOAgeW9k+OBpuOBr+OBvuOBo+OBpuOBhOOCi+OBi++8iFJlc2lkdWFsIFItc3F1YXJlZO+8ieOCguOBv+OCi+OBk+OBqOOBjOOBp+OBjeOBvuOBmeOAggoKYGBge3J9CmRmX2dkcHBjYXAyIHw+IGZpbHRlcih5ZWFyID09IDIwMjIsIHJlZ2lvbiAhPSJBZ2dyZWdhdGVzIikgfD4gCiAgZHJvcF9uYShnZHAsIHBvcCkgfD4gbG0obG9nMTAoZ2RwKSB+IGxvZzEwKHBvcCksIGRhdGEgPSBfKSB8PiBzdW1tYXJ5KCkKYGBgCgpTdGVwIDIxLiDlnLDln5/jgoTjgIHlj47lhaXjg6zjg5njg6vjgoLoibLjgoTjgIHlvaLjgafooajnpLrjgZnjgovjgZPjgajjgYzlj6/og73jgafjgZnjgIIKCmBgYHtyfQpkZl9nZHBwY2FwMiB8PiBmaWx0ZXIoeWVhciA9PSAyMDIwLCByZWdpb24gIT0iQWdncmVnYXRlcyIpIHw+IAogIGRyb3BfbmEoZ2RwLCBwb3ApIHw+IAogIGdncGxvdChhZXMocG9wLCBnZHAsIGNvbG9yID0gcmVnaW9uLCBzaGFwZSA9IGluY29tZSkpICsgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpCmBgYAoKU3RlcCAyMi4g44GT44KM44Gv44CB5LiA5Lq65b2T44Gf44KK44GuIEdEUCDjgpLlnLDln5/jgajjgIHkurrlj6Pjga7mg4XloLHjgoLlhaXjgozjgabooajnpLrjgZfjgZ/jgoLjga7jgafjgZnjgIIKCmBgYHtyfQpkZl9nZHBwY2FwMiB8PiBmaWx0ZXIoeWVhciA9PSAyMDIwLCByZWdpb24gIT0iQWdncmVnYXRlcyIpIHw+IAogIGRyb3BfbmEoZ2RwLCBnZHBwY2FwLCBwb3ApIHw+IAogIGdncGxvdChhZXMoZ2RwcGNhcCwgZ2RwLCBjb2xvciA9IHJlZ2lvbiwgc2l6ZSA9IHBvcCkpICsgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpCmBgYAoKU3RlcCAyMy4g5LuW44Gu44OR44OD44Kx44O844K444KS5L2/44GG44Go44CB5a++6Kmx5Z6L44Gu44Kw44Op44OV44KS5L2c5oiQ44GZ44KL44GT44Go44KC5Y+v6IO944Gn44GZ44CCCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikKYGBgCgpTdGVwIDIzLiDjgZPjgozjga/jgIHkuIDkurrlvZPjgZ/jgorjga4gR0RQIOOCkuWcsOWfn+OBqOOAgeS6uuWPo+OBruaDheWgseOCguWFpeOCjOOBpuihqOekuuOBl+OBn+OCguOBruOBp+OBmeOAggoKYGBge3J9CmxpYnJhcnkocGxvdGx5KQp0ZXN0IDwtIGRmX2dkcHBjYXAyIHw+IGZpbHRlcih5ZWFyID09IDIwMjAsIHJlZ2lvbiAhPSJBZ2dyZWdhdGVzIikgfD4gZHJvcF9uYShnZHAsIHBvcCkgfD4gCiAgZ2dwbG90KGFlcyhjb2xvciA9IGNvdW50cnksIHNoYXBlID0gcmVnaW9uLCBwb3AsIGdkcCkpICsgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQp0ZXN0IHw+IGdncGxvdGx5KCkKYGBgCgpTdGVwIDI0LiDkuIDkurrlvZPjgZ/jgorjga5HRFAg44GuMjAyMuW5tOOBruWIhuW4g+OCkuOBv+OBpuOBv+OBvuOBl+OCh+OBhuOAggoKYGBge3J9CmRmX2dkcHBjYXAgfD4gZmlsdGVyKHllYXIgPT0gMjAyMiwgcmVnaW9uICE9ICJBZ2dyZWdhdGVzIikgfD4gZHJvcF9uYShnZHBwY2FwKSB8PiAKICBnZ3Bsb3QoYWVzKGdkcHBjYXApKSArIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMTAwMDApCmBgYAoKU3RlcCAyNS4g5a++5pWw6KGo56S644Gr44GZ44KL44Go44Gp44GG44Gq44KL44Gn44GG44GG44GL44CCCgpgYGB7cn0KZGZfZ2RwcGNhcCB8PiBmaWx0ZXIoeWVhciA9PSAyMDIyLCByZWdpb24gIT0gIkFnZ3JlZ2F0ZXMiKSB8PiBkcm9wX25hKGdkcHBjYXApIHw+IAogIGdncGxvdChhZXMoZ2RwcGNhcCkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwKSArIHNjYWxlX3hfbG9nMTAoKQpgYGAKClN0ZXAgMjYuIOeuseOBsuOBkuWbs+OBp+imi+OBpuOBv+OBvuOBl+OCh+OBhuOAggoKYGBge3J9CmRmX2dkcHBjYXAyIHw+IGZpbHRlcih5ZWFyID09IDIwMjApIHw+IGRyb3BfbmEoZ2RwcGNhcCkgfD4gCiAgZmlsdGVyKGluY29tZSAhPSAiQWdncmVnYXRlcyIpIHw+IAogIGdncGxvdChhZXMoZ2RwcGNhcCwgZmFjdG9yKGluY29tZSwgbGV2ZWxzID0gYygiSGlnaCBpbmNvbWUiLCAiVXBwZXIgbWlkZGxlIGluY29tZSIsICJMb3dlciBtaWRkbGUgaW5jb21lIiwgIkxvdyBpbmNvbWUiKSksIGZpbGwgPSBpbmNvbWUpKSArIGdlb21fYm94cGxvdCgpICsgc2NhbGVfeF9sb2cxMCgpICsKICBsYWJzKHkgPSAiIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCg==